﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using SAPPDI.Entitys;
using TestImpresion.Annotations;

namespace TestImpresion.Clases
{
    public class ImprentaFormulario : INotifyPropertyChanged
    {

        private FormularioCompletoEncuadernado _encuadernadoFormulario;
        public FormularioCompletoEncuadernado EncuadernadoFormulario
        {
            get
            {
                return _encuadernadoFormulario;
            }
            set
            {
                _encuadernadoFormulario = value;
                NotifyPropertyChanged("EncuadernadoFormulario");
            }
        }

        private FormularioCompletoInsertos _insertosFormulario;
        public FormularioCompletoInsertos InsertosFormulario
        {
            get
            {
                return _insertosFormulario;
            }
            set
            {
                _insertosFormulario = value;
                NotifyPropertyChanged("InsertosFormulario");
            }
        }

        private FormularioCompletoInteriores _interioresFormulario;
        public FormularioCompletoInteriores InterioresFormulario
        {
            get
            {
                return _interioresFormulario;
            }
            set
            {
                _interioresFormulario = value;
                NotifyPropertyChanged("InterioresFormulario");
            }
        }

        private int _tiraje;
        public int Tiraje
        {
            get
            {
                return _tiraje;
            }
            set
            {
                _tiraje = value;
                NotifyPropertyChanged("Tiraje");
            }
        }

        private InteriorInfo _valoresInterior;

        public InteriorInfo ValoresInterior
        {
            get
            {
                return _valoresInterior;
            }
            set
            {
                _valoresInterior = value;
                NotifyPropertyChanged("ValoresInterior");
            }
        }

        private List<InsertoInfo> _valoresInsertos;

        public List<InsertoInfo> ValoresInsertos
        {
            get
            {
                return _valoresInsertos;
            }
            set
            {
                _valoresInsertos = value;
                NotifyPropertyChanged("ValoresInsertos");
            }
        }

        private EncuadernadoInfo _valoresEncuadernado;

        public EncuadernadoInfo ValoresEncuadernado
        {
            get
            {
                return _valoresEncuadernado;
            }
            set
            {
                _valoresEncuadernado = value;
                NotifyPropertyChanged("ValoresEncuadernado");
            }
        }

        private CostoTotalInfo _valoresCostoTotal;

        public CostoTotalInfo ValoresCostoTotal
        {
            get
            {
                return _valoresCostoTotal;
            }
            set
            {
                _valoresCostoTotal = value;
                NotifyPropertyChanged("ValoresCostoTotal");
            }
        }

        private double _pliegos;

        private double _costoPliegosInterioes;

        public TestImpresion.MainPage Parent;

        private void CalculaPliegos()
        {
            var size = this.InterioresFormulario.InterioresFormulario.CurrentInteriores.TamañoPagina;
            var paginas = this.InterioresFormulario.InterioresFormulario.CurrentInteriores.Paginas;
            _pliegos = ((paginas / 2) / Convert.ToDouble((int)size));
            //  _pliegos = Convert.ToInt32(_pliegos * this.Tiraje);
        }

        private void CostoPliegos()
        {
            this.InterioresFormulario.InterioresFormulario.ComprarInterioesFormulario =
                this.Parent.GetComprarPorInterioes();
            var costo = this.InterioresFormulario.InterioresFormulario.ComprarInterioesFormulario.CostoPliegos;
            _costoPliegosInterioes = _pliegos * costo;
        }

        public InteriorInfo CalculaValoresInteriores()
        {
            this.CalculaPliegos();
            this.CostoPliegos();
            var pliego = new Pliego(this.InterioresFormulario.InterioresFormulario.CurrentInteriores.PliegoSeleccionado);
            _pliegos = _pliegos *((int)
                       this.InterioresFormulario.InterioresFormulario.ComprarInterioesFormulario.PliegoSeleccionado
                           .MedidaPagina);
            pliego.DividePliego(this.InterioresFormulario.InterioresFormulario.CurrentInteriores.TamañoPagina);

            this._valoresInterior = new InteriorInfo
                {

                    Gramaje = this.InterioresFormulario.InterioresFormulario.CurrentInteriores.Gramaje,
                    Ispuntos = this.InterioresFormulario.InterioresFormulario.CurrentInteriores.IsPuntos,
                    Medida = new Pliego(pliego),
                    Paginas = this.InterioresFormulario.InterioresFormulario.CurrentInteriores.Paginas,
                    Tintas = this.InterioresFormulario.InterioresFormulario.CurrentInteriores.GetTintas(),
                    PliegosPorInterior = _pliegos,
                    TotalPliegos = _pliegos * this.Tiraje,
                    TotalPliegosConMargen = _pliegos * this.Tiraje * 1.15,
                    CostoAcabados = this.InterioresFormulario.InterioresFormulario.ComprarInterioesFormulario.CostoImpresion,
                    CostoPliegoindividual = this.InterioresFormulario.InterioresFormulario.ComprarInterioesFormulario.CostoPliegos,
                    TipoPapel = this.InterioresFormulario.InterioresFormulario.CurrentInteriores.SelectedTipoPapel == null ? string.Empty : this.InterioresFormulario.InterioresFormulario.CurrentInteriores.SelectedTipoPapel.ToString(),
                    Papel = this.InterioresFormulario.InterioresFormulario.CurrentInteriores.SelectedPapel == null ? string.Empty : this.InterioresFormulario.InterioresFormulario.CurrentInteriores.SelectedPapel.ToString()
                };
            _valoresInterior.CostoLotePliegos = _valoresInterior.TotalPliegosConMargen * _valoresInterior.CostoPliegoindividual;
            _valoresInterior.CostoTintas = (_valoresInterior.GetCostoTintas() *
                                            this._valoresInterior.TotalPliegosConMargen) +
                                           this._valoresInterior.GetCostoPlacasTintas();
            _valoresInterior.CostoImpresionMargenTintas = (_valoresInterior.GetCostoTintas()*
                                                           this._valoresInterior.TotalPliegosConMargen);
            _valoresInterior.CostoImpresionTintas = (_valoresInterior.GetCostoTintas() *
                                                          this._valoresInterior.TotalPliegos);
            return this._valoresInterior;
        }

        public List<InsertoInfo> CalculaValoresInsertos()
        {
            var lisaInsertos = new List<InsertoInfo>();
            var medida = this.InterioresFormulario.InterioresFormulario.CurrentInteriores.TamañoPagina;
            var noinserto = 0;
            var pliego = new Pliego(this.InterioresFormulario.InterioresFormulario.CurrentInteriores.PliegoSeleccionado);
            pliego.DividePliego(medida);
            foreach (var inserto in this.InsertosFormulario.InsertosFormulario.ListaInsertos)
            {

                var nuevoInserto = new InsertoInfo
                    {
                        Gramaje = inserto.Gramaje,
                        Paginas = inserto.Paginas,
                        Ispuntos = inserto.IsPuntos,
                        Tintas = inserto.GetTintas(),
                        Medida = new Pliego(pliego),
                        TipoPapel = inserto.SelectedTipoPapel == null ? string.Empty : inserto.SelectedTipoPapel.ToString(),
                        Papel = inserto.SelectedPapel == null ? string.Empty : inserto.SelectedPapel.Nombre,
                        Posicion = inserto.SelectedEntrePliegos == null ? string.Empty : inserto.SelectedEntrePliegos.Descripcion,
                        SujetoSuelto = inserto.IsSuelto ? "Suelto" : "Sujeto"
                    };
                var pliegos = (double)((double)((Convert.ToDouble(nuevoInserto.Paginas) / 2)) / (int)medida);
                nuevoInserto.PliegosPorElemento = pliegos;
                nuevoInserto.TotalPliegos = (pliegos * this.Tiraje);
                nuevoInserto.TotalPliegosConMargen = nuevoInserto.TotalPliegos * 1.15;
                nuevoInserto.CostoPliegoindividual = this.InsertosFormulario.InsertosFormulario.ListaComprarPor[noinserto].CostoPliegos;
                nuevoInserto.CostoLotePliegos =
                    (Convert.ToInt32(nuevoInserto.TotalPliegosConMargen) * nuevoInserto.CostoPliegoindividual);

                nuevoInserto.CostoAcabados =
                    this.InsertosFormulario.InsertosFormulario.ListaComprarPor[noinserto].CostoImpresion;

                nuevoInserto.CostoTintas = (nuevoInserto.GetCostoTintas() *
                                nuevoInserto.TotalPliegosConMargen) +
                               nuevoInserto.GetCostoPlacasTintas();
                nuevoInserto.CostoImpresionMargenTintas = (nuevoInserto.GetCostoTintas() *
                                                     nuevoInserto.TotalPliegosConMargen);
                nuevoInserto.CostoImpresionTintas = (nuevoInserto.GetCostoTintas() *
                                                              nuevoInserto.TotalPliegos);
                lisaInsertos.Add(nuevoInserto);

                noinserto++;
            }
            this._valoresInsertos = lisaInsertos;
            return this._valoresInsertos;
        }

        public EncuadernadoInfo CalculaValoresEncuadernado()
        {
            //para calcular el encuadernado necesitamos saber las medidas de los interiores e incertos

            this.CalculaValoresInteriores();
            this.CalculaValoresInsertos();
            var infoencuadernado = new EncuadernadoInfo();
            this.EncuadernadoFormulario.EncuadernadoFormulario.ComprarEncuadernadoFormulario =
                Parent.GetComprarPorEncuadernado();

            infoencuadernado.EspesorInsertos = this._valoresInsertos.Sum(inserto => inserto.Paginas==1?inserto.GetGramosCm():(double)(((double)inserto.Paginas / 2) * inserto.GetGramosCm()));
            infoencuadernado.EspesorInteriores = (double)(((double)this._valoresInterior.Paginas / 2) * this._valoresInterior.GetGramosCm());
            infoencuadernado.Lomo = infoencuadernado.EspesorInteriores + infoencuadernado.EspesorInsertos;
            infoencuadernado.AnchoSinMargen = ((this._valoresInterior.Medida.Ancho * 2)) +
                 this.EncuadernadoFormulario.EncuadernadoFormulario.CurrentEncuadernado.Volado + this.EncuadernadoFormulario.EncuadernadoFormulario.CurrentEncuadernado.SolapaUno
                 + this.EncuadernadoFormulario.EncuadernadoFormulario.CurrentEncuadernado.SolapaDos;

            infoencuadernado.Ancho = infoencuadernado.AnchoSinMargen + 1 + infoencuadernado.Lomo;

            infoencuadernado.AltoSinMargen = this._valoresInterior.Medida.Alto + (!this.EncuadernadoFormulario.EncuadernadoFormulario.CurrentEncuadernado.SoloHorizontal ?
                this.EncuadernadoFormulario.EncuadernadoFormulario.CurrentEncuadernado.Volado : 0);

            infoencuadernado.Alto = infoencuadernado.AltoSinMargen + 1;
            infoencuadernado.MedidaComprar =
                this.EncuadernadoFormulario.EncuadernadoFormulario.ComprarEncuadernadoFormulario.PliegoSeleccionado;
            var encAncho = this.EncuadernadoFormulario.EncuadernadoFormulario.ComprarEncuadernadoFormulario.PliegoSeleccionado.Ancho / infoencuadernado.Ancho;
            var
        encAlto = this.EncuadernadoFormulario.EncuadernadoFormulario.ComprarEncuadernadoFormulario.PliegoSeleccionado.Alto / infoencuadernado.Alto;

            infoencuadernado.PiezasEnPliego = encAncho > 1 && encAlto > 1 ? Math.Floor(encAncho) * Math.Floor(encAlto) : Math.Floor( Math.Min(encAncho, encAlto));

            infoencuadernado.PliegosPorTiraje = ((1 / infoencuadernado.PiezasEnPliego) * this.Tiraje);

            infoencuadernado.PliegosPorTirajeConMargen = infoencuadernado.PliegosPorTiraje * 1.15;

            infoencuadernado.Papel = this.EncuadernadoFormulario.EncuadernadoFormulario.CurrentEncuadernado.SelectedPapel == null ? string.Empty :
                this.EncuadernadoFormulario.EncuadernadoFormulario.CurrentEncuadernado.SelectedPapel.ToString();
            infoencuadernado.TipoPapel = this.EncuadernadoFormulario.EncuadernadoFormulario.CurrentEncuadernado.SelectedTipoPapel == null ? string.Empty :
                this.EncuadernadoFormulario.EncuadernadoFormulario.CurrentEncuadernado.SelectedTipoPapel.ToString();
            infoencuadernado.Gramaje = this.EncuadernadoFormulario.EncuadernadoFormulario.CurrentEncuadernado.Gramaje;
            infoencuadernado.Ispuntos = this.EncuadernadoFormulario.EncuadernadoFormulario.CurrentEncuadernado.IsPuntos;
            infoencuadernado.TipoPasta =
                this.EncuadernadoFormulario.EncuadernadoFormulario.CurrentEncuadernado.GetTipoPasta();
            infoencuadernado.CostoPliegoindividual =
                this.EncuadernadoFormulario.EncuadernadoFormulario.ComprarEncuadernadoFormulario.CostoPliegos;
            infoencuadernado.CostoAcabados =
                this.EncuadernadoFormulario.EncuadernadoFormulario.ComprarEncuadernadoFormulario.CostoImpresion;
            infoencuadernado.CostoLotePliegos = infoencuadernado.CostoPliegoindividual *
                                                infoencuadernado.PliegosPorTirajeConMargen;


            infoencuadernado.CostoPliegoEmpastado = infoencuadernado.PliegosPorTiraje * 3.36;

            infoencuadernado.CostoPliegoMargenEmpastado = infoencuadernado.PliegosPorTirajeConMargen * 3.36;

            infoencuadernado.Tintas = this.EncuadernadoFormulario.EncuadernadoFormulario.CurrentEncuadernado.GetTintas();
            infoencuadernado.CostoTintas = (infoencuadernado.GetCostoTintas() *
                                infoencuadernado.PliegosPorTirajeConMargen) +
                               infoencuadernado.GetCostoPlacasTintas();


            infoencuadernado.CostoImpresionMargenTintas = (infoencuadernado.GetCostoTintas() *
                                               infoencuadernado.PliegosPorTirajeConMargen);
            infoencuadernado.CostoImpresionTintas = (infoencuadernado.GetCostoTintas() *
                                                          infoencuadernado.PliegosPorTiraje);
            this._valoresEncuadernado = infoencuadernado;

            return this._valoresEncuadernado;
        }


        public void ImprimeResultados()
        {
            //calculamos toos los valores
            this.CalculaValoresEncuadernado();
            this.ValoresCostoTotal = new CostoTotalInfo
                {
                    CostoTotalPliegos = this.ValoresInterior.CostoLotePliegos +
                                        this.ValoresEncuadernado.CostoLotePliegos
                };
            this.ValoresCostoTotal.CostoTotalPliegos += this.ValoresInsertos.Sum(elemento => elemento.CostoLotePliegos);
            this.ValoresCostoTotal.CostoTotalTintas = this.ValoresInterior.CostoTintas +
                                                      this.ValoresEncuadernado.CostoTintas;
            this.ValoresCostoTotal.CostoTotalTintas += this.ValoresInsertos.Sum(elemento => elemento.CostoTintas);
            this.ValoresCostoTotal.CostoEmpastado = this.ValoresEncuadernado.CostoPliegoEmpastado;
            this.ValoresCostoTotal.CostoFlete = 4000;
            this.ValoresCostoTotal.CostoTotalImprenta = this.ValoresCostoTotal.CostoEmpastado +
                                                       this.ValoresCostoTotal.CostoFlete +
                                                       this.ValoresCostoTotal.CostoTotalTintas;

            this.ValoresCostoTotal.CostoTotaCotizado = this.ValoresCostoTotal.CostoTotalImprenta +
                                                       this.ValoresCostoTotal.CostoTotalPliegos;
        }

        public ImprentaFormulario()
        {
            this._interioresFormulario = new FormularioCompletoInteriores(this);
            this._insertosFormulario = new FormularioCompletoInsertos() { ParentImprenta = this };
            this._encuadernadoFormulario = new FormularioCompletoEncuadernado() { ParentImprenta = this };
        }

        public event PropertyChangedEventHandler PropertyChanged;

        [NotifyPropertyChangedInvocator]
        protected virtual void NotifyPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}
